#include "tipo_dato_compuesto.h"

TipoDatoCompuesto::TipoDatoCompuesto(bool obligatorio):TipoDato(obligatorio){
}

TipoDatoCompuesto::~TipoDatoCompuesto(){
	this->clear();
}

void TipoDatoCompuesto::clear(){
	std::vector< TipoDato* >::iterator it = elementos.begin();
	while (it != elementos.end()) {
		if ((*it) != NULL)	
			delete(*it);
		it++;
	}
	elementos.clear();
}

void TipoDatoCompuesto::set_obligatorio(bool b){
	this->obligatorio = b;
}

bool TipoDatoCompuesto::esta_cargado() const{
	bool cargado = true;
	if (elementos.size() == 0)
		cargado = false;
	std::vector< TipoDato* >::const_iterator it = elementos.begin();
	while ((it != elementos.end()) && (cargado)) {
			TipoDato* aux = (*it);
			cargado = ((aux->esta_cargado()) || (!aux->es_obligatorio()));
			it++;
	}
	return cargado;
}
		 
bool TipoDatoCompuesto::elementos_iguales(const TipoDatoCompuesto * dato) const{
		
	if(this->get_tamanio() != dato->get_tamanio() )
		throw std::runtime_error("No tienen el mismo tamanio");
	
	std::vector< TipoDato* >::const_iterator it = elementos.begin();
	std::vector< TipoDato* >::const_iterator it2 = dato->elementos.begin();
	bool result = true;
	while ((it != elementos.end()) && (result)) {
		TipoDato* copia = (*it);
		TipoDato* orig = (*it2);
		if ((copia != NULL) && (orig != NULL))	
			result = (*copia == *orig);
		else
			result = false;  
		it++;
		it2++;
	}
	return result;
}
bool TipoDatoCompuesto::elementos_menores (const TipoDatoCompuesto * dato) const{
	if(this->get_tamanio() != dato->get_tamanio() )
		throw std::runtime_error("No son el mismo tipo de struct");
	
	std::vector< TipoDato* >::const_iterator it = elementos.begin();
	std::vector< TipoDato* >::const_iterator it2 = dato->elementos.begin();
	bool result = true;
	while ((it != elementos.end()) && (result)) {
		TipoDato* copia = (*it);
		TipoDato* orig = (*it2);
		if ((copia != NULL) && (orig != NULL))	
			result = (*copia < *orig);
		else
			result = false;  
		it++;
		it2++;
	}
	return result;	
	
}
	 
bool TipoDatoCompuesto::quitar_dato(unsigned int ind){
	if (ind >= elementos.size() )
		return false;
	std::vector< TipoDato* >::iterator it = elementos.begin();
	unsigned int cont = 0;
	while (( it != elementos.end() ) && (cont < ind)) {
			it++;
			cont++;
	}
	if (it != elementos.end() ) {
		delete *it;
		elementos.erase(it);
		return true;
	}
	return false;
}
	  
TipoDato& TipoDatoCompuesto::operator[] (size_t indice) throw (ExcepIndiceDesbordado) {
	if (indice >= elementos.size())
		throw ExcepIndiceDesbordado("Indice desbordado");
	return *(elementos[indice]);
}

void TipoDatoCompuesto::copiar_elementos(TipoDatoCompuesto * dato ) const{
	std::vector< TipoDato* >::const_iterator it = this->elementos.begin();
	while (it != this->elementos.end()) {
		dato->add_dato(*(*it));
		it++;
	}
	
}
